package models

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/v2/bson"
	"go.mongodb.org/mongo-driver/v2/mongo"
	"go.mongodb.org/mongo-driver/v2/mongo/options"
	"strings"
	"time"
	"zbn-oil-consumption/config"
	"zbn-oil-consumption/utils"
)

type Car struct {
	Id             *bson.ObjectID `bson:"_id,omitempty" json:"id"`
	UserId         int64          `bson:"user_id" json:"userId"`
	Name           string         `bson:"name" json:"name"`
	Brand          string         `bson:"brand" json:"brand"`
	Model          string         `bson:"model" json:"model"`
	PlateNumber    string         `bson:"plate_number" json:"plateNumber"`
	FuelType       string         `bson:"fuel_type" json:"fuelType"`
	TankCapacity   int            `bson:"tank_capacity" json:"tankCapacity"`
	InitialMileage int            `bson:"initial_mileage" json:"initialMileage"`
	PurchaseDate   string         `bson:"purchase_date" json:"purchaseDate"`
	Remark         string         `bson:"remark" json:"remark"`
	CreatedAt      time.Time      `bson:"created_at" json:"createdAt"`
}

func (Car) Add(data Car) (id interface{}, err error) {
	ctx := context.Background()
	c := config.Db.Collection("cars")
	res, err := c.InsertOne(ctx, data)
	if err != nil {
		return
	}
	id = res.InsertedID
	return
}

func (Car) FindByUserId(userId int64) (Car, error) {
	ctx := context.Background()
	var res Car
	filter := bson.M{"user_id": userId}
	err := config.Db.Collection("cars").FindOne(ctx, filter).Decode(&res)
	return res, err
}

func (Car) ExistByUserId(userId int64) (bool, error) {
	ctx := context.Background()
	var res Car
	filter := bson.M{"user_id": userId}
	err := config.Db.Collection("cars").FindOne(ctx, filter).Decode(&res)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			return false, nil
		}
		return false, err
	}
	return true, err
}

func (Car) Update(data Car) (id int64, err error) {
	ctx := context.Background()
	c := config.Db.Collection("cars")
	filter := bson.M{"user_id": data.UserId}
	update := bson.M{
		"$set": bson.M{
			"name":            data.Name,
			"brand":           data.Brand,
			"model":           data.Model,
			"plate_umber":     data.PlateNumber,
			"fuel_type":       data.FuelType,
			"tank_capacity":   data.TankCapacity,
			"initial_mileage": data.InitialMileage,
			"purchase_date":   data.PurchaseDate,
			"remark":          data.Remark,
		},
	}
	res, err := c.UpdateOne(ctx, filter, update)
	if err != nil {
		return
	}
	id = res.ModifiedCount
	return
}

func (Car) Delete(data Car) (count int64, err error) {
	ctx := context.Background()
	c := config.Db.Collection("cars")
	filter := bson.M{}
	filter["_id"] = data.Id
	res, err := c.DeleteOne(ctx, filter)
	if err != nil {
		return
	}
	count = res.DeletedCount
	return
}

func (Car) GetList(params utils.Params) (total int64, res []Car, err error) {
	ctx := context.Background()
	skip := (params.Page - 1) * params.PageSize
	findOptions := options.Find()
	findOptions.SetSkip(int64(skip))
	findOptions.SetLimit(int64(params.PageSize))
	filter := bson.M{}
	if strings.TrimSpace(params.Name) != "" {
		filter["brand"] = strings.TrimSpace(params.Name)
	}
	c := config.Db.Collection("cars")
	total, err = c.CountDocuments(ctx, filter)
	if err != nil {
		return 0, nil, err
	}
	// 执行查询
	cursor, err := c.Find(ctx, filter, findOptions)
	if err != nil {
		return 0, nil, fmt.Errorf("find failed: %w", err)
	}
	defer cursor.Close(ctx)
	err = cursor.All(ctx, &res)
	return
}
